package com.util.service;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.UUID;

import org.apache.commons.codec.binary.Hex;
import org.apache.commons.io.FilenameUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.util.Assert;
import org.springframework.web.multipart.MultipartFile;

import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3Client;
import com.amazonaws.services.s3.model.CannedAccessControlList;
import com.amazonaws.services.s3.model.ObjectMetadata;
import com.amazonaws.services.s3.model.PutObjectRequest;
import com.exception.CommonException;
import com.exception.SnsResultCode;
import com.util.file.DateTimeUtil;
import com.util.file.FileMetadata;

/**
 * 파일 저장 서비스 <br/>
 * 
 */
public class FileStoreServiceImpl implements ApplicationContextAware {

	protected Logger logger = LoggerFactory.getLogger(this.getClass());

	private String fileHomeDir = "/files/";

	
	
	/**
	 * 사용자 프로필 사진
	 * @param file
	 * @param thumbnailSize
	 * @return
	 * @throws CommonException
	 */
	public FileMetadata storeImage(MultipartFile file, String group) throws CommonException {
		return storeFile(group, file);
	}
	

	/**
	 * 파일 확장자 및 종류에 따라 이미지 저장
	 * 
	 * @param group
	 * @param type
	 * @param srcFile
	 * @param thumbnailSize
	 * @return
	 * @throws SnsException
	 */
	public FileMetadata storeFile(String group, MultipartFile srcFile) throws CommonException {
		Assert.notNull(srcFile, "File must not be null");

		FileMetadata metadata = new FileMetadata(fileHomeDir);
		
		ObjectMetadata objmeta = new ObjectMetadata();
		
		
		try {
			String filename = srcFile.getOriginalFilename();
			String ext = FilenameUtils.getExtension(filename);			
			
			metadata.setFile_name(filename);
			
			String baseDir = (group == null ? "" : group + File.separator) + getTodayWithDirName() +  File.separator;	
			
			// 파일 이름 변경
			String destFilename = uuid() + "." + ext;
			String file_path = FilenameUtils.separatorsToUnix(baseDir + destFilename);
			
			metadata.setFile_path(file_path);			
			
			uploadFileToS3(srcFile, file_path, objmeta);  //아마존으로 감			
			
			
			logger.debug("image <{}>", metadata.getFile_path());
		} catch (Exception e) {
			logger.error("Error: {}", e.getMessage(), e);
			// 예외 발생시 저장된 파일 삭제
			if (metadata != null)
				metadata.delete();
			throw new CommonException(SnsResultCode.FAIL_FILE_UPLOAD);
		}
		return metadata;
	}	
	
	
	
	public void uploadFileToS3 (MultipartFile srcFile, String file_path, ObjectMetadata metadata) throws IOException  {
			
			long fileSize = srcFile.getSize();
			
			String AWS_BUCKETNAME = "lifeonfile";
			String AWS_ACCESS_KEY = "AKIAINZPUJKCC3IHV43Q";
			String AWS_SECRET_ACCESS_KEY = "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";
			
			InputStream inputStream = null;			
			
			
			try{
				if(fileSize >0) {
					inputStream = srcFile.getInputStream();
					
					AWSCredentials credentials = new BasicAWSCredentials(AWS_ACCESS_KEY, AWS_SECRET_ACCESS_KEY);
					AmazonS3 s3  = new AmazonS3Client(credentials);	
					
					metadata.setContentLength(fileSize);					
					
					PutObjectRequest putObjectRequest = new PutObjectRequest(AWS_BUCKETNAME, file_path, inputStream, metadata);
					putObjectRequest.setCannedAcl(CannedAccessControlList.PublicReadWrite);
					
					s3.putObject(putObjectRequest);											
				}
			}catch(IOException e){
				
			}finally{
				if(inputStream != null)	inputStream.close();
			}
			
			
	}
	
	

	/**
	 * @param fileHomeDir
	 *            the fileHomeDir to set
	 */
	public void setFileHomeDir(String fileHomeDir) {
		this.fileHomeDir = fileHomeDir;
	}

	

	private String getTodayWithDirName() {
		return DateTimeUtil.getDateToString(null, DateTimeUtil.DIRECTORY_DATE_FORMAT);
	}	

	public static final String uuid() {
		UUID uuid = UUID.randomUUID();
		long msb = uuid.getMostSignificantBits();
		long lsb = uuid.getLeastSignificantBits();
		byte[] buffer = new byte[16];
		for (int i = 0; i < 8; i++) {
			buffer[i] = (byte) (msb >>> 8 * (7 - i));
		}
		for (int i = 8; i < 16; i++) {
			buffer[i] = (byte) (lsb >>> 8 * (7 - i));
		}
		return new String(Hex.encodeHex(buffer));
	}

	@Override
	public void setApplicationContext(ApplicationContext applicationContext)
			throws BeansException {
		// TODO Auto-generated method stub
		
	}


}
